package com.gobang.controller;

import com.gobang.domain.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 日志演示控制器
 * 演示各种日志级别和使用场景
 * 
 * @author Gobang Team
 */
@Slf4j
@RestController
@RequestMapping("/log-demo")
public class LogDemoController {

    /**
     * 演示所有日志级别
     */
    @GetMapping("/all-levels")
    public Result<String> allLevels() {
        log.trace("这是 TRACE 级别日志 - 最详细的信息");
        log.debug("这是 DEBUG 级别日志 - 调试信息");
        log.info("这是 INFO 级别日志 - 重要业务信息");
        log.warn("这是 WARN 级别日志 - 警告信息");
        log.error("这是 ERROR 级别日志 - 错误信息");
        
        return Result.success("已输出所有级别的日志，请查看控制台");
    }

    /**
     * 演示带参数的日志
     */
    @GetMapping("/with-params")
    public Result<String> withParams(@RequestParam(defaultValue = "张三") String username,
                                      @RequestParam(defaultValue = "25") Integer age) {
        // 单个参数
        log.info("用户名：{}", username);
        
        // 多个参数
        log.info("用户信息 - 姓名：{}，年龄：{}", username, age);
        
        // 复杂对象
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("username", username);
        userInfo.put("age", age);
        userInfo.put("timestamp", System.currentTimeMillis());
        log.debug("完整用户信息：{}", userInfo);
        
        return Result.success("已输出带参数的日志");
    }

    /**
     * 演示异常日志
     */
    @GetMapping("/with-exception")
    public Result<String> withException(@RequestParam(defaultValue = "false") Boolean trigger) {
        try {
            if (trigger) {
                // 模拟业务处理
                log.info("开始处理业务逻辑");
                processBusinessLogic();
            }
            return Result.success("处理成功");
        } catch (Exception e) {
            // 正确的异常日志记录方式
            log.error("业务处理失败", e);
            return Result.fail("处理失败：" + e.getMessage());
        }
    }

    /**
     * 演示条件日志
     */
    @GetMapping("/conditional")
    public Result<String> conditionalLog() {
        // 检查日志级别后再执行复杂操作
        if (log.isDebugEnabled()) {
            String complexInfo = buildComplexInfo();
            log.debug("复杂信息：{}", complexInfo);
        }
        
        if (log.isTraceEnabled()) {
            log.trace("TRACE 级别已启用");
        }
        
        return Result.success("条件日志演示完成");
    }

    /**
     * 演示业务流程日志
     */
    @PostMapping("/business-flow")
    public Result<Map<String, Object>> businessFlow(@RequestBody Map<String, Object> request) {
        String orderId = UUID.randomUUID().toString();
        
        // 1. 记录业务开始
        log.info("========== 订单处理开始 ==========");
        log.info("订单ID：{}", orderId);
        log.debug("请求参数：{}", request);
        
        try {
            // 2. 参数验证
            log.debug("步骤1：验证参数");
            validateParams(request);
            
            // 3. 业务处理
            log.debug("步骤2：处理业务逻辑");
            processOrder(orderId, request);
            
            // 4. 保存数据
            log.debug("步骤3：保存数据");
            saveData(orderId);
            
            // 5. 记录成功
            log.info("订单处理成功，订单ID：{}", orderId);
            log.info("========== 订单处理结束 ==========");
            
            Map<String, Object> result = new HashMap<>();
            result.put("orderId", orderId);
            result.put("status", "success");
            return Result.success(result);
            
        } catch (Exception e) {
            log.error("订单处理失败，订单ID：{}", orderId, e);
            log.info("========== 订单处理结束（失败） ==========");
            throw e;
        }
    }

    /**
     * 演示循环中的日志优化
     */
    @GetMapping("/batch-process")
    public Result<String> batchProcess(@RequestParam(defaultValue = "100") Integer count) {
        log.info("开始批量处理，数量：{}", count);
        
        int successCount = 0;
        int failureCount = 0;
        
        for (int i = 0; i < count; i++) {
            try {
                // ❌ 不推荐：在循环中输出大量日志
                // log.debug("处理第 {} 条数据", i);
                
                // 模拟处理
                if (Math.random() > 0.1) {
                    successCount++;
                } else {
                    failureCount++;
                }
            } catch (Exception e) {
                // ✅ 推荐：只在出错时记录
                log.error("处理第 {} 条数据失败", i, e);
                failureCount++;
            }
        }
        
        // ✅ 推荐：输出汇总日志
        log.info("批量处理完成 - 总数：{}，成功：{}，失败：{}", 
                count, successCount, failureCount);
        
        return Result.success(String.format("处理完成：成功 %d，失败 %d", successCount, failureCount));
    }

    /**
     * 演示性能敏感的日志
     */
    @GetMapping("/performance")
    public Result<String> performanceLog() {
        long startTime = System.currentTimeMillis();
        
        // ❌ 不推荐：不必要的字符串拼接
        // log.info("处理时间：" + (System.currentTimeMillis() - startTime) + "ms");
        
        // ✅ 推荐：使用占位符
        log.info("处理开始");
        
        // 模拟业务处理
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        long endTime = System.currentTimeMillis();
        log.info("处理完成，耗时：{}ms", endTime - startTime);
        
        return Result.success("性能日志演示完成");
    }

    // ==================== 辅助方法 ====================

    private void processBusinessLogic() {
        throw new RuntimeException("模拟业务异常");
    }

    private String buildComplexInfo() {
        // 模拟复杂的信息构建
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 10; i++) {
            sb.append("数据").append(i).append("; ");
        }
        return sb.toString();
    }

    private void validateParams(Map<String, Object> request) {
        if (request == null || request.isEmpty()) {
            log.warn("参数为空");
            throw new IllegalArgumentException("参数不能为空");
        }
        log.debug("参数验证通过");
    }

    private void processOrder(String orderId, Map<String, Object> request) {
        // 模拟订单处理
        log.debug("处理订单：{}", orderId);
    }

    private void saveData(String orderId) {
        // 模拟数据保存
        log.debug("保存订单数据：{}", orderId);
    }
}

